#ifndef __WTYPE_H
#define __WTYPE_H
#include <cstdint>
#include <stdio.h>

typedef unsigned long long int U64;
typedef unsigned int U32;
typedef unsigned short U16;
typedef unsigned char U8;
typedef char S8;
typedef short S16;
typedef int S32;
typedef long long int S64;
typedef float F32;
typedef __int128_t int128_t;

typedef union
{
	U32 hex;
	float real;
} FloatHex;

typedef struct
{
	FloatHex real;
	FloatHex virt;
} FloatComplex;

typedef union
{
	U32 word[4];
	S32 sword[4];

	U16 hword[8];
	S16 shword[8];

	U8 byte[16];

	U64 dword[2];
	S64 sdword[2];

	F32 f[4];
} Reg128;

typedef union
{
	U32 word[2];
	S32 sword[2];

	U16 hword[4];
	S16 shword[4];

	U8 byte[8];

	U64 dword;
	S64 sdword;

	F32 f[2];
} Reg64;

typedef union
{
	U32 word;
	S32 sword;

	U16 hword[2];
	S16 shword[2];

	U8 byte[4];

	F32 f;
} Reg32;

typedef struct fbs
{
    int s : 1;
    unsigned e : 9;
    long long m : 50;
} FloatBs;

/**
 * 向量指令参数
 * in1_type:u31每次跟根据设置的类型自动读取指定输入数据长度,与输入数据定义的类型无关
 * 如:输入定义的是.word 0x12345678, in1_type=1 u31自动先读取低16bit 0x5678, in1_type=2 则自动读32bit 0x12345678;
 *    输入定义的是.short 0x5678 0x1234, in1_type=1 u31自动先读取16bit 0x5678, in1_type-2 则自动读取32bit 0x56781234
 * num:按上述规则读多少次
 * 当num读的数据长度大于输入定义的数据长度时,u31不会报错,会紧接着adr_in1的地址往后继续读,内存越界
 *
 */
typedef struct
{
	int8_t flag;			// word1[22:20]: bit22=1 向量运算完乘产生向量运算中断和完成标志 bit20~21 向量运算中断号,允许产生4个不同中断
	int8_t in1_mode;		// word2[31]: bit31=0 第一组数据输入模式 0:固定的数 1:数组
	int16_t num;			// word2[30:20] 循环次数(一次都多少个数据),最大2047(mat和mat_t时需等于第一个矩阵的宽)
	void *adr_in1;			// word1[19:0] 第一组输入数据地址, bit19=1 第一组输入数据地址从寄存器读取,寄存器地址为bit0~5,只支持r32~38;bit19=0 则bit0~18全为地址
	void *adr_in2;			// word2[19:0] 第二组输入数据地址,格式同adr_in1
	int8_t cmd_mode;		// word3[31:27] bit27=1:正常模式 bit28=1:最大值 bit29=1:最小值 bit30=1:求和 bit31=1:均值
	int8_t in1_type;		// word3[26:25] 第一组数据类型  1:16bit 2:32bit 3:64bit(只有复数指令支持该数据类型)
	int8_t in2_en;			// word3[24] 第二组输入数据是否有效
	int8_t in2_mode;		// word3[23] 第二组输入数据模式 0:固定的数 1:数组
	void *adr_out;			// word3[19:0] 输出地址 格式同adr_in1
	int32_t out_size;		// 自定义 输出长度 避免重复计算
	int8_t in2_type;		// word3[22:21] 第二组数据类型 1:16bit 2:32bit 3:64bit(只有复数指令支持该数据类型)
	int8_t out_type;		// word3[20] 输出数据类型 0:16bit 1:32bit
	uint16_t overflow_flag; // 溢出标志
} VectorParam;

typedef struct
{
	void *data_ptr;
	int32_t data_size;
	int64_t sum;
	int32_t max;
	int32_t min;
	int32_t avg;
} VectorResult;

typedef struct
{
	FILE *mem_upasm_file;
	FILE *upinc_file;
	FILE *upasm_file;
	// FILE *comm_upinc_file;
} U31CodeFile;

#endif // !__WTYPE_H
